// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

#ifndef CFM_H_
#define CFM_H_

#include <stdint.h>
#include <stddef.h>
#include "status/rot_status.h"
#include "crypto/hash.h"
#include "crypto/rsa.h"
#include "manifest/manifest.h"


/**
 * Defines a component FW signed image.
 */
struct cfm_component_signed_img {
	uint8_t failure_action;							/**< Flag indicating action to take if validation fails. */
	const uint8_t *digest;							/**< Image digest */
	uint16_t digest_length;							/**< The length of the signed image digest. */
};

/**
 * Defines a component FW.
 */
struct cfm_component_firmware {
	struct cfm_component_signed_img *imgs;			/**< A list of component signed images */
	const char *fw_version_id;						/**< Firmware version ID. */
	uint16_t version_length;						/**< The length of the version identifier. */
	size_t img_count;									/**< The number of signed images making up the firmware. */
};

/**
 * Defines a component.
 */
struct cfm_component {
	uint32_t component_id;							/**< Component device identifier */
	struct cfm_component_firmware *fw;    			/**< A list of component FW */
	size_t fw_count;								/**< The number of component firmware in the list. */
};

/**
 * A list of components IDs.
 */
struct cfm_component_ids {
	const uint32_t *ids;							/**< The list of component IDs. */
	size_t count;									/**< The number of component IDs in the list. */
};

/**
 * The API for interfacing with a cfm file.
 */
struct cfm {
	struct manifest base;							/**< Manifest interface */

	/**
	 * Get the list of supported component IDs advertised in the CFM.
	 *
	 * @param cfm The CFM to query.
	 * @param ids A structure to be updated with the list of supported component IDs.
	 *
	 * @return 0 if the IDs list was updated successfully or an error code.
	 */
	int (*get_supported_component_ids) (struct cfm *cfm, struct cfm_component_ids *ids);

	/**
	 * Free a list of component IDs.
	 *
	 * @param cfm CFM instance that provided component IDs list.
	 * @param ids The component IDs list to free.
	 */
	void (*free_component_ids) (struct cfm *cfm, struct cfm_component_ids *ids);

	/**
	 * Get component structure that has same component ID
	 *
	 * @param cfm The CFM to query.
	 * @param component_id The component ID to query.
	 * @param component A structure to be updated with the component information.
	 *
	 * @return 0 if the component was updated successfully or an error code.
	 */
	int (*get_component) (struct cfm *cfm, uint32_t component_id, struct cfm_component *component);

	/**
	 * Free a component.
	 *
	 * @param cfm CFM instance that provided component.
	 * @param component Structure that holds component to free.
	 */
	void (*free_component) (struct cfm *cfm, struct cfm_component *component);
};


#define	CFM_ERROR(code)		ROT_ERROR (ROT_MODULE_CFM, code)

/**
 * Error codes that can be generated by a CFM.
 */
enum {
	CFM_INVALID_ARGUMENT = CFM_ERROR (0x00),			/**< Input parameter is null or not valid. */
	CFM_NO_MEMORY = CFM_ERROR (0x01),					/**< Memory allocation failed. */
	CFM_GET_COMPONENT_IDS_FAILED = CFM_ERROR (0x02),	/**< The list of component IDs was not generated. */
	CFM_GET_COMPONENT_FAILED = CFM_ERROR (0x03),		/**< The component information was not generated. */
	CFM_UNKNOWN_COMPONENT = CFM_ERROR (0x04),			/**< The component identifier is not present in the CFM. */
};


#endif /* CFM_H_ */
